
#include <BSurface>
#include <BFileDialog>
#include <BReadWrite>

#include "BasicsHandler.h"
#include "PushHandler.h"
#include "PointHandler.h"
#include "HingeHandler.h"
#include "SliderHandler.h"
#include "ConearHandler.h"
#include "SixdofHandler.h"
#include "DynamicScene.h"
#include "MainWindow.h"

MainWindow::MainWindow()
{
	DynamicScene* scene = new DynamicScene();

	BSurface* surface = new BSurface(100, 100, 10, 10);
	surface->setOrientation(Orientation_Vertical);
	surface->setPolyMode(Poly_Line);
	surface->setColor(255, 130, 60);
	surface->setLighting(false);
	surface->setPosition(-50, -50, 0);
	scene->insert(surface);

	BCamera* camera = new BCamera();
	camera->setPosition(0, -16, 0);
	camera->setCenter(0, 0, 0);
	camera->setFovy(36);
	camera->setNear(BReal(0.1));
	camera->setFar(1000);
	camera->setColor(23, 34, 45);

	_mainHandler = new MainHandler();

	_treeWidget = new BTreeWidget();
	{
		BTreeItem* samplesItem = _treeWidget->addTopItem("Samples");
		samplesItem->addChild("Basics")->setAsset(new BasicsHandler);

		BTreeItem* item = _treeWidget->addTopItem("Constraints");
		item->addChild("Push")->setAsset(new PushHandler);
		item->addChild("Point")->setAsset(new PointHandler);
		item->addChild("Hinge")->setAsset(new HingeHandler);
		item->addChild("Slider")->setAsset(new SliderHandler);
		item->addChild("Conear")->setAsset(new ConearHandler);
		item->addChild("Sixdof")->setAsset(new SixdofHandler);
	}

	_viewer = new BViewer();
	_viewer->setScene(scene);
	_viewer->setCamera(camera);
	_viewer->setHandler(_mainHandler);

	_stackLayout = new BStackLayout();
	_stackLayout->setHeightPolicy(Policy_Dynamic);
	{
		_propertyBoard = new PropertyBoard(this);
		_propertyBoard->setHeightPolicy(Policy_Preferred);
		_constraintBoard = new ConstraintBoard(this);
		_constraintBoard->setHeightPolicy(Policy_Preferred);
		_stackLayout->addWidget(_propertyBoard, Align_TopCenter);
		_stackLayout->addWidget(_constraintBoard, Align_TopCenter);
	}

	BHBoxLayout* splitter = new BHBoxLayout();
	{
		splitter->addWidget(_treeWidget, 1);
		splitter->addWidget(_viewer, 10);
		splitter->addLayout(_stackLayout);
	}

	BHBoxLayout* buttonLayout = new BHBoxLayout();
	buttonLayout->setWidthPolicy(Policy_Preferred);
	{
		_importButton = new BButton("import");
		_resetButton = new BButton("reset");
		_playButton = new BButton("play");
		_pauseButton = new BButton("pause");
		_loopCheckBox = new BCheckBox("loop");

		buttonLayout->addWidget(_importButton);
		buttonLayout->addSpacer(100);
		buttonLayout->addWidget(_resetButton);
		buttonLayout->addWidget(_playButton);
		buttonLayout->addWidget(_pauseButton);
		buttonLayout->addWidget(_loopCheckBox);
		buttonLayout->addSpacer(100);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(splitter, 100);
	vlayout->addLayout(buttonLayout);

	connect("edit-node", &MainWindow::slotEditNode);
	connect("edit-constraint", &MainWindow::slotEditConstraint);

	connect(_importButton, Signal_Clicked, &MainWindow::slotImportButtonClicked);
	connect(_resetButton, Signal_Clicked, &MainWindow::slotResetClicked);
	connect(_playButton, Signal_Clicked, &MainWindow::slotPlayClicked);
	connect(_pauseButton, Signal_Clicked, &MainWindow::slotPauseClicked);
	connect(_treeWidget, Signal_ItemDoubleClicked, &MainWindow::slotTreeItemDoubleClicked);
	connect(_loopCheckBox, Signal_Checked, &MainWindow::slotLoopChecked);

	_loopCheckBox->setChecked(true);

}

void MainWindow::slotImportButtonClicked()
{
	const BString& fileName = BFileDialog::OpenFile("Import Node");
	if (fileName.size())
	{
		BNode* node = ReadFile<BNode>(fileName);
		_viewer->scene()->insert(node);
	}
}
void MainWindow::slotPlayClicked(BObject* object, const BValue& value)
{

}
void MainWindow::slotResetClicked(BObject* object, const BValue& value)
{

}
void MainWindow::slotPauseClicked(BObject* object, const BValue& value)
{

}
void MainWindow::slotTreeItemDoubleClicked(BObject* object, const BValue& value)
{
	BTreeItem* item = value;
	_mainHandler->clearChildren();
	if (BHandler* handler = item->asset())
	{
		_mainHandler->addChild(handler);
	}
}
void MainWindow::slotLoopChecked(BObject* object, const BValue& value)
{

}
void MainWindow::slotEditNode(BObject* object, const BValue& value)
{
	if (BNode* node = value)
	{
		_propertyBoard->setAsset(value);
		_stackLayout->setCurrent(_propertyBoard);
		return;
	}
}
void MainWindow::slotEditConstraint(BObject* object, const BValue& value)
{
	if (BConstraint* constraint = value)
	{
		_constraintBoard->setAsset(value);
		_stackLayout->setCurrent(_constraintBoard);
		return;
	}
}

void MainWindow::showEvent(const BEvent& event)
{
	BMainWindow::showEvent(event);
	BSphereHandler* handler = (BSphereHandler*)_viewer->handler();
	handler->focus();
}

void MainWindow::updateEvent(const BEvent& event)
{

}
